local skel = fk.CreateSkill{
  name = "lb__zhenshu",
}

Fk:loadTranslationTable{
  ["lb__zhenshu"] = "镇戍",
  [":lb__zhenshu"] = "每轮开始时，你可以指定一名其他角色，本轮双方可互相为对方响应伤害牌，且当你需要响应伤害牌时，你可以弃置一张牌以视为响应之（每回合每种类型限一张）。",

  ["@lb__zhenshu-round"] = "镇戍",
  ["@lb__zhenshu-turn"] = "镇戍",
  ["#lb__zhenshu"] = "镇戍：你可以选择一名其他角色，本轮你与其可互相为对方响应伤害牌",
  ["#lb__zhenshu_ask"] = "镇戍：你可以为 %dest 响应 %arg",
  ["#lb__zhenshu_choose_slash"] = "镇戍：你可以弃置一张牌并视为使用一张【杀】，用以响应 %arg",
  ["#lb__zhenshu_choose_jink"] = "镇戍：你可以弃置一张牌并视为使用一张【杀】/【闪】，用以响应 %arg",

  ["$lb__zhenshu1"] = "奉陪到底。",
  ["$lb__zhenshu2"] = "我以朗道之名。",
}

skel:addEffect(fk.RoundStart, {
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(skel.name) and table.find(player.room:getOtherPlayers(player), function (to)
      return to.rest == 0
    end)
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local tos = table.filter(player.room:getOtherPlayers(player), function (to)
      return to.rest == 0
    end)
    if #tos > 0 then
      tos = room:askToChoosePlayers(player, {
        min_num = 1,
        max_num = 1,
        skill_name = skel.name,
        targets = tos,
        prompt = "#lb__zhenshu",
        cancelable = true,
      })
      if #tos > 0 then
        event:setCostData(self, {tos = tos})
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local to = event:getCostData(self).tos[1]
    player.room:setPlayerMark(player, "@lb__zhenshu-round", to)
    player.room:addTableMarkIfNeed(player, "lb__yongyi", to.id)
  end,
})

skel:addEffect(fk.AskForCardResponse, {
  anim_type = "defensive",
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(skel.name) and player:getMark("@lb__zhenshu-round") ~= 0 and data.skillName ~= skel.name then
      local to = player:getMark("@lb__zhenshu-round")
      return not to.dead and (target == player or target == to)
      and data.eventData and data.eventData.card and data.eventData.card.is_damage_card
    end

  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local to = player:getMark("@lb__zhenshu-round") ---@type ServerPlayer
    if to and room:askToSkillInvoke(target == player and to or player, {
        skill_name = skel.name,
        prompt = "#lb__zhenshu_ask::"..target.id..":"..data.eventData.card:toLogString()
      }) then
      local respond = room:askToResponse(target == player and to or player, {
        pattern = data.pattern,
        skill_name = skel.name,
        extra_data = data.extraData,
        event_data = data.eventData,
        prompt = "#lb__zhenshu_ask::"..target.id..":"..data.eventData.card:toLogString(),
        cancelable = true,
      })
      if respond then
        event:setCostData(self, {respond = respond})
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local respond = event:getCostData(self).respond ---@type RespondCardDataSpec
    if respond then
      local result = {
        from = target,
        card = respond.card,
      }
      data.result = result
      return true
    end
  end,
})

skel:addEffect(fk.AskForCardUse, {
  anim_type = "defensive",
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(skel.name) and player:getMark("@lb__zhenshu-round") ~= 0 and data.skillName ~= skel.name then
      local to = player:getMark("@lb__zhenshu-round")
      return not to.dead and (target == player or target == to)
      and data.eventData and data.eventData.card and data.eventData.card.is_damage_card
    end

  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local to = player:getMark("@lb__zhenshu-round") ---@type ServerPlayer
    if to and room:askToSkillInvoke(target == player and to or player, {
        skill_name = skel.name,
        prompt = "#lb__zhenshu_ask::"..target.id..":"..data.eventData.card:toLogString()
      }) then
      local respond = room:askToUseCard(target == player and to or player, {
        pattern = data.pattern,
        skill_name = skel.name,
        extra_data = data.extraData,
        event_data = data.eventData,
        prompt = "#lb__zhenshu_ask::"..target.id..":"..data.eventData.card:toLogString(),
        cancelable = true,
      })
      if respond then
        event:setCostData(self, {respond = respond})
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local respond = event:getCostData(self).respond ---@type UseCardDataSpec
    if respond then
      respond.from = target
      data.result = respond
      return true
    end
  end,
})

skel:addEffect(fk.AskForCardResponse, {
  priority = 0.9,
  anim_type = "defensive",
  can_trigger = function (self, event, target, player, data)
    return target == player and player:hasSkill(skel.name) and player:getMark("@lb__zhenshu-round") ~= 0
    and data.eventData and data.eventData.card and data.eventData.card.is_damage_card
    and table.find(player:getCardIds("he"), function (id)
      local card = Fk:getCardById(id)
      return not player:prohibitDiscard(id) and not table.contains(player:getTableMark("@lb__zhenshu-turn"), card:getTypeString())
    end)
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local list = {}
    for _, name in ipairs(Fk:getAllCardNames("btde")) do
      if Exppattern:Parse(data.pattern):matchExp(name.."|.|.|.|.") then
        table.insert(list, name)
      end
    end
    if #list == 0 then return end
    local ids = table.filter(player:getCardIds("he"), function (id)
      local card = Fk:getCardById(id)
      return not player:prohibitDiscard(id) and not table.contains(player:getTableMark("@lb__zhenshu-turn"), card:getTypeString())
    end)
    if #ids == 0 then return end
    local s, ret = room:askToUseActiveSkill(player,{
      skill_name = "#lb__zhenshu_choose",
      prompt = "#lb__zhenshu_choose_ask:::"..data.eventData.card:toLogString(),
      cancelable = true,
      extra_data = {
        skillName = skel.name,
        extra_data = {
          name = data.eventData.card:toLogString(),
          list = list,
          ids = ids
        },
      }
    })
    if s and ret and ret.cards and ret.interaction then
      event:setCostData(self, {cards = ret.cards, name = ret.interaction})
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local name = event:getCostData(self).name
    local cards = event:getCostData(self).cards
    room:throwCard(cards, skel.name, player)
    room:addTableMark(player, "@lb__zhenshu-turn", Fk:getCardById(cards[1]):getTypeString())
    local result = {
      from = target,
      card = Fk:cloneCard(name),
    }
    data.result = result
    return true
  end,
})

local zhenshu_spec = {
  priority = 0.9,
  anim_type = "defensive",
  can_trigger = function (self, event, target, player, data)
    return target == player and player:hasSkill(skel.name) and player:getMark("@lb__zhenshu-round") ~= 0
    and (data.extraData == nil or not data.extraData.lb__zhenshu_ask)
    and data.eventData and data.eventData.card and data.eventData.card.is_damage_card
    and Exppattern:Parse(data.pattern):matchExp("slash,jink")
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local ids = table.filter(player:getCardIds("he"), function (id)
      local card = Fk:getCardById(id)
      return not player:prohibitDiscard(id) and not table.contains(player:getTableMark("@lb__zhenshu-turn"), card:getTypeString())
    end)
    if Exppattern:Parse(data.pattern):matchExp("slash") and event == fk.AskForCardUse then
      local extraData = table.simpleClone(data.extraData)
      extraData.lb__zhenshu_ask = true
      local use = room:askToUseVirtualCard(player, {
        name = "slash",
        skill_name = skel.name,
        prompt = "#lb__zhenshu_choose_slash:::"..data.eventData.card:toLogString(),
        cancelable = true,
        card_filter = {
          n = 1,
          cards = ids,
        },
        skip = true,
        extra_data = extraData,
        event_data = data.eventData,
      })
      if use then
        local cards = table.clone(use.card.subcards)
        use.card.subcards = {}
        event:setCostData(self, {cards = cards, use = use})
        return true
      end
    else
      local cards = room:askToDiscard(player, {
        min_num = 1,
        max_num = 1,
        skill_name = skel.name,
        prompt = "#lb__zhenshu_choose_jink:::"..data.eventData.card:toLogString(),
        cancelable = true,
        skip = true,
        include_equip = true,
        pattern = tostring(Exppattern{ id = ids}),
      })
      if #cards > 0 then
        event:setCostData(self, {cards = cards})
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local use = event:getCostData(self).use
    local cards = event:getCostData(self).cards
    room:throwCard(cards, skel.name, player)
    room:addTableMark(player, "@lb__zhenshu-turn", Fk:getCardById(cards[1]):getTypeString())
    if use then
      data.result = use
    else
      data.result = {
        from = player,
        card = Fk:cloneCard( Exppattern:Parse(data.pattern):matchExp("slash") and "slash" or "jink"),
        tos = {},
      }
    end
    return true
  end,
}

skel:addEffect(fk.AskForCardUse, zhenshu_spec)
skel:addEffect(fk.AskForCardResponse, zhenshu_spec)

return skel